#include "header.h"

extern LogFile *mainLogFile;
std::map<uint16_t,int> statusNeighborNodes;
void *commandLineThreadFunction(void *ptr);
pthread_mutex_t LogFileLock;

int main(int argc, char *argv[])
{	
	printf("Main Thread CREATED\n");
	commandLine(argc,argv);															//Call function to Parse Command Line

	node.ParseStartupConfigFile(startupFile);


	char hostName[50];															//Get the name of the host you are running on
	memset(hostName,'\0',50*sizeof(char));
	gethostname(hostName, sizeof(hostName));
	node.setHostName(hostName);
	//printf("Host = %s\n",hostName);


	
	node.setNodeID(node.getHostName(), node.getPort());								// NODE ID 
	node.setNodeInstanceID(node.getNodeID());										// NODE INSTANCE ID

	node.VerifyIfHomeDirectoryExists();												// check if home directory exists.

																												//AUTOSHUTDOWN TIMER
	iretAutoShutdownThread = pthread_create(&autoShutdownThread,NULL, autoShutdown, NULL);																					


										
																						//LOG FILE AND COMMANDLINE THREAD
	if(resetFlag == 1)															// if reset is in commond line argument
	{
		remove(node.getLogFilename().c_str());			
	}
	// create a new log file to enter all the log details
	mainLogFile  = new LogFile(node.getHomeDir()+"/"+node.getLogFilename(),1);
	//Clear the map of the status nodes.
	statusNeighborNodes.clear();
	pthread_mutex_init(&LogFileLock,NULL);
	// create the command line thread
	pthread_create(&commandLineThread,NULL,commandLineThreadFunction,NULL);	
													

		
	//printf("SIZE OF BEACON LIST IS = %d\n",node.getBeaconList().size());
	multimap<string,uint16_t> tempBeacon = node.getBeaconList();

	pthread_t connectThread[node.getBeaconList().size()];										// connect thread to create connection between Beacon nodes

	multimap<string,uint16_t>::iterator ii;															// CHECK IF YOU ARE BEACON   
	
	for( ii=tempBeacon.begin(); ii!=tempBeacon.end(); ii++)
	{       
		//printf("Host NameX = %s\n",(*ii).first.c_str());
		//printf("PortX = %hu\n",(*ii).second);

		//printf("Host name = %s\n",node.getHostName());
		//printf("Port = %hu\n",node.getPort());
		if(((*ii).first == node.getHostName()) && (*ii).second == node.getPort())
		{
			IsBeaconNode = true;
			printf("I am a beacon node\n");
			break;
		}
	}

	
	int i=0;
	if(IsBeaconNode)														// if node is BEACON node
	{
		//printf("Is Beacon Node true\n");
		//printf("Beacon size = %d\n", node.getBeaconList().size());
		joinToTheNetworkFlag = false;		// ignore soft restart
																											//SERVER THREAD CREATED
																											//DISPATCHER THREAD CREATED
																											//MSG LIFE TIME THREAD CREATED
		iretServerThread = pthread_create(&serverThread, NULL, server, (void *)node.getPort()); 			//http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
		iretDispatcherThread = pthread_create(&dispatcherThread, NULL, dispatcher, NULL); 			
		iretMsgLifeTimerThread = pthread_create(&msgLifeTimerThread, NULL, msgLifeTimer, NULL);



		for( ii=tempBeacon.begin(); ii!=tempBeacon.end(); ii++)
		{   
			
				
			if(((*ii).first == node.getHostName()) && (*ii).second == (node.getPort() ))				// IF my host name and port number then continue
			{
				printf("MY HOST NAME AND PORT NAME = %s %d \n",(*ii).first.c_str(), (*ii).second);
				continue;
			}
			else
			{
				char *beaconNamePort = (char *)malloc(100 *sizeof(char));
				memset(beaconNamePort,'\0',100*sizeof(char));
				sprintf(beaconNamePort, "%s %u",(*ii).first.c_str(),(*ii).second);					//concat host name and port
				beaconNamePort[strlen(beaconNamePort)+1]='\0';
				//printf("beaconNamePort = %s\n",beaconNamePort);

				iretConnectThread = pthread_create(&connectThread[i++], NULL, connect,(void *) beaconNamePort);		//CREATE CONNECT THREAD ALONG WITH THE HOST NAME & PORT NUMBER OF OTHER BEACON NODE
			}		
		}

		/*for(int i=0 ; i<(int)node.getBeaconList().size() ;i++)
		{
			pthread_join( connectThread[i], NULL);
		}*/
			
		//pthread_join(serverThread,NULL);
		//pthread_join(dispatcherThread,NULL);
		//pthread_join(msgLifeTimerThread,NULL);

				
		
	}
	else																//if node is NOT BEACON node
	{
		//*********************** JOIN ************ in functions.cpp file ****************************************************
		JoinToTheNetwork();						
		//pthread_join(serverThread,NULL);
		//pthread_join( dispatcherThread, NULL);
		//pthread_join( msgLifeTimerThread, NULL);

	}
	
	//pthread_join(serverThread,NULL);
	//pthread_join(dispatcherThread,NULL);
	//pthread_join(msgLifeTimerThread,NULL);
	
	pthread_mutex_lock(&ReadQueue);													//APPLY LOCK
	pthread_cond_signal(&condition_var_Read);	
	pthread_mutex_unlock(&ReadQueue);													

	printf("SIGNAL SENT TO READ QUEUE\n");
	printf("MAIN THREAD EXIT\n");
	pthread_exit(NULL);
	return 0;
}
